<template>
    <div ref="cgsChart" style="width: 100%; height: 100%"></div>
</template>

<script>
import {chartColors} from "@/constant"
import { DataType } from "@/filterConstant"
import { convertFromStringToDateTime } from "@/util/date"
export default {
  name: 'cgsEcharts',
  props:{
	  type: String,
	  title: String,
	  data: Array,
	  x: Array,
	  y: Array,
	  colors: Array,
	  limits: Array,
  },
  data(){
      return {
          option:{
            title: {
                text: '',
                textStyle: {
                    color: '#000'
                }
            },
            color: [],
            legend: {
                left: 'center'
            },
            tooltip: {
                trigger: 'axis',
                axisPointer: {            // 坐标轴指示器，坐标轴触发有效
                    type: 'shadow'        // 默认为直线，可选为：'line' | 'shadow'
                }
            },
            grid: {
                top: '50px',
                left: '4%',
                right: '4%',
                bottom: '4%',
                containLabel: true
            },
            series: [],
            xAxis: null,
            yAxis: null,
          },
      }
  },
  methods:{
	resize(newHPx, newWPx){
		if(this.myChart){
            this.myChart.resize()
        }
	},
    init(){
        this.option.title.text = this.title

        if(this.x.length === 1){
            let data = this.data.find(d => d.name === this.x[0].field)
            this.xData = data?.data || []
        } else {
            this.xData = []
        }

        if(Array.isArray(this.colors)){
            let newColor = this.colors.map(c => c.value)
            let color = [...chartColors]
            for (let i = 0; i < newColor.length; i++) {
                color[i] = newColor[i];
            }
            this.option.color = color
        }

        if(this.type !== 'pie') {
            this.option.xAxis = {
                type: 'category',
                data:  Array.from(new Set(this.xData))
            }
            this.option.yAxis = {
                type: 'value', minInterval: 1
            }
        }else {
            this.option.xAxis = null
            this.option.yAxis = null
            this.option.legend = null
        }
        
        this.createSeriesData()
	},
    createSeriesData(){
        let {x, option} = this
        if(!this.x || this.x.length === 0) return
		if(!this.data || this.data.length === 0) return
		if(!this.y || this.y.length === 0) return
		if(this.limits && this.limits.find(c => c.field === '')) return
		if(!this.limits) this.limits = []
        
        let xData = this.xData
		let series = []
        this.y.forEach((y, i) => {
            let {computeType, rename, field} = y
            let yTotal = {}, yData = [], newYTotal = {}
            let data = this.data.find(d => d.name === field)?.data || []
            let setXData = Array.from(new Set(xData))
            setXData.forEach(d => yTotal[d] = [])
            let classDate = []
            for(let j = 0 ; j < data.length; j ++) {
                yTotal[xData[j]].push(data[j])
                
                if(x[0].dataType === DataType.DATE){
                    if(x[0].groupType === 'year'){
                        let date = convertFromStringToDateTime(xData[j])
                        classDate.push(`${date.year}`)
                    }
                    else if(x[0].groupType === 'mouth'){
                        let date = convertFromStringToDateTime(xData[j])
                        classDate.push(`${date.year}-${date.mouth}`)
                    }
                    else if(x[0].groupType === 'day'){
                        let date = convertFromStringToDateTime(xData[j])
                        classDate.push(`${date.year}-${date.mouth}-${date.day}`)
                    }
                    else if(x[0].groupType === 'hour'){
                        let date = convertFromStringToDateTime(xData[j])
                        classDate.push(`${date.year}-${date.mouth}-${date.day} ${date.hour}`)
                    }
                    else if(x[0].groupType === 'minute'){
                        let date = convertFromStringToDateTime(xData[j])
                        classDate.push(`${date.year}-${date.mouth}-${date.day} ${date.hour}:${date.minute}`)
                    }
                }
            }
            if(x[0].dataType === DataType.DATE){
                classDate = Array.from(new Set(classDate))
                classDate.forEach(d => newYTotal[d] = [])
                classDate.forEach(d => {
                    for (const yt in yTotal) {
                        if(yt.includes(d)){
                            newYTotal[d] = [...newYTotal[d], ...yTotal[yt]]
                        }
                    }
                })
                yTotal = newYTotal
                option.xAxis.data = classDate
            }
			let limits = this.limits.filter(limit => limit.field === y.field)
            for (const key in yTotal) {
				let totalData = 0
				let itemStyle = null
                switch(computeType){
                    case 'sum':
                        totalData = yTotal[key].reduce((prev,current)=>{
                            return prev + current
                        })
                        break
                    case 'mean':
                        totalData = yTotal[key].reduce((prev,current)=>{
                            return prev + current
                        }) / yTotal[key].length
                        break
                    case 'max':
                        totalData = Math.max(...yTotal[key])
                        break
                    case 'min':
                        totalData = Math.min(...yTotal[key])
                        break
                    case 'count':
                        totalData = yTotal[key].length
                        break
                }
				if(limits){
					limits.forEach(limit => {
						let limitObj = {
							color: limit.colorValue
						}
						switch(limit.limitType){
							case 'greater': 
								itemStyle = totalData > limit.limitValue ? limitObj : null 
							break;
							case 'less': 
								itemStyle = totalData < limit.limitValue ? limitObj : null 
							break;
							case 'equal':
								itemStyle = totalData = limit.limitValue ? limitObj : null 
							break;
							case 'greater_equal': 
								itemStyle = totalData >= limit.limitValue ? limitObj : null 
							break;
							case 'less_equal': 
								itemStyle = totalData <= limit.limitValue ? limitObj : null 
							break;
							case 'between': 
								itemStyle = (totalData > limit.front && data < limit.later) ? limitObj : null 
							break;
						}
					})
				}
				yData.push({
					value: totalData,
					itemStyle
				})
            }
            
            let obj = {
                type: this.type,
                data: yData,
                name: rename,
                connectNulls: true
            }
            
            if(this.type === 'line') {
                obj.smooth = true
                obj.areaStyle = {
                    normal:{
                        //颜色渐变函数 前四个参数分别表示四个位置依次为左、下、右、上
                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                            offset: 0,
                            color: this.option.color[i].replace('1)', '0.40)')
                        },{
                            offset: 1,
                            color: 'rgba(38,197,254,0.00)'
                        }])

                }}
            } else if (this.type === 'pie') {
                if(this.y.length > 1 && i > 0) {
                    this.$message.warning('饼图不能展示两个或以上指标数据，仅展示首位指标数据')
                    return
                }
                obj.radius = ['40%', '70%'];
                obj.itemStyle = {
                    borderRadius: 2
                }
                obj.data = obj.data.map((d, k) => ({value: d.value, name: setXData[k]}))
            }
            series.push(obj)
            // console.log(yTotal);
        })
        // console.log(this.option);
        this.option.series = series
    }
  },
  watch:{
    option:{
        deep:true,
        handler: function(){
            if(this.myChart) {                
		        this.myChart.setOption(this.option, true);
            }
        }
    },
    type:{
        deep:true,
        handler: function(){
            if(this.type !== 'pie') {
                this.option.xAxis = {
                    type: 'category',
                    data: Array.from(new Set(this.xData))
                }
                this.option.yAxis = { type: 'value', minInterval: 1}
                this.option.tooltip = {
                    trigger: 'axis',
                    axisPointer: {            // 坐标轴指示器，坐标轴触发有效
                        type: 'shadow'        // 默认为直线，可选为：'line' | 'shadow'
                    }
                }
            }else {
                this.option.xAxis = null
                this.option.yAxis = null
                this.option.legend = null
                this.option.tooltip = {
                    trigger: 'item',
                    formatter: '{a} <br/>{b}: {c} ({d}%)'
                }
            }
            this.createSeriesData()
        }
    },
    title:{
        deep:true,
        handler: function(){
            this.option.title.text = this.title
        }
    },
    data:{
        deep:true,
        handler: function(){
            let data = this.data.find(d => d.name === this.x[0].field)
            this.xData = data.data
            if(this.option.xAxis) {
                this.option.xAxis = {
                    type: 'category',
                    data: Array.from(new Set(this.xData))
                }
            }
            this.createSeriesData()
        }
    },
    x:{
        deep:true,
        handler: function(){
            if(this.x.length === 1){
                let data = this.data.find(d => d.name === this.x[0].field)
                this.xData = data.data
            } else {
                this.xData = []
            }
            if(this.option.xAxis) {
                this.option.xAxis = {
                    type: 'category',
                    data: Array.from(new Set(this.xData))
                }
            }
            this.createSeriesData()
        }
    },
    y:{
        deep:true,
        handler: function(){
            this.createSeriesData()
        }
    },
    colors:{
        deep:true,
        handler: function(){
            let newColor = this.colors.map(c => c.value)
            let color = [...chartColors]
            for (let i = 0; i < newColor.length; i++) {
                color[i] = newColor[i];
            }
            this.option.color = color
        }
    },
    limits:{
        deep:true,
        handler: function(){
            this.createSeriesData()
        }
    },
  },
  mounted() {
	this.myChart = this.$echarts.init(this.$refs['cgsChart']);
    this.init()
  }
}
</script>

<style>
</style>
